#ifndef PORTABLE_MACROS_H_
#define PORTABLE_MACROS_H_

#include <cstddef>

namespace portable {

#define P_UNLIKELY(condition) (__builtin_expect(!!(condition), 0))
#define P_LIKELY(condition) (__builtin_expect(!!(condition), 1))
#define AWINLINE inline __attribute__((always_inline))
#define NOINLINE __attribute__((noinline))

// Explicitly declare the assignment operator as deleted.
// Note: This macro is deprecated and will be removed soon. Please explicitly
// delete the assignment operator instead.
#define DISALLOW_ASSIGN(TypeName) TypeName& operator=(const TypeName&) = delete

// Explicitly declare all implicit constructors as deleted, namely the
// default constructor, copy constructor and operator= functions.
// This is especially useful for classes containing only static methods.
#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
  TypeName() = delete;                           \
  TypeName(const TypeName&) = delete;            \
  DISALLOW_ASSIGN(TypeName)

// The arraysize(arr) macro returns the # of elements in an array arr.
// The expression is a compile-time constant, and therefore can be
// used in defining new arrays, for example.  If you use arraysize on
// a pointer by mistake, you will get a compile-time error.
#define arraysize(array) (sizeof(ArraySizeHelper(array)))

// This template function declaration is used in defining arraysize.
// Note that the function doesn't need an implementation, as we only
// use its type.
template <typename T, size_t N>
char (&ArraySizeHelper(T (&array)[N]))[N];

}  // namespace portable

#endif  // PORTABLE_MACROS_H_
